﻿
// CDrawView.cpp: CDrawView 类的实现
//

#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义，并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "Draw.h"
#endif

#include "CDrawDoc.h"
#include "CDrawView.h"
#include "CLine.h"
#include "CPenCil.h"
#include "CRectO.h"
#include "CEllipse.h"
#include "CRRect.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CDrawView

IMPLEMENT_DYNCREATE(CDrawView, CScrollView)

BEGIN_MESSAGE_MAP(CDrawView, CScrollView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CScrollView::OnFilePrintPreview)
	ON_COMMAND_RANGE(ID_DRAW_DRAG, ID_DRAW_ALL, &CDrawView::OnDrawTools)
	ON_UPDATE_COMMAND_UI_RANGE(ID_DRAW_DRAG, ID_DRAW_ALL, &CDrawView::OnUpdateDrawTools)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_ERASEBKGND()
	ON_WM_SIZE()
	ON_WM_SETCURSOR()
END_MESSAGE_MAP()

// CDrawView 构造/析构

CDrawView::CDrawView() noexcept
{
	// TODO: 在此处添加构造代码

}

CDrawView::~CDrawView()
{
}

BOOL CDrawView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CScrollView::PreCreateWindow(cs);
}

// CDrawView 绘图

void CDrawView::OnDraw(CDC* pDC)
{
	// 背景重置白色
	CRect rect;
	GetClientRect(rect);
	m_dc.FillSolidRect(rect, 0xffffff);

	int nCount = m_ls.GetCount();
	for (int i = 0; i < nCount; i++) {
		m_ls[i]->OnDraw(&m_dc);
	}

	// 实际绘制
	pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &m_dc, 0, 0, SRCCOPY);
}

void CDrawView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();

	CSize sizeTotal;
	// TODO: 计算此视图的合计大小
	sizeTotal.cx = sizeTotal.cy = 100;
	SetScrollSizes(MM_TEXT, sizeTotal);
}


// CDrawView 打印

BOOL CDrawView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CDrawView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void CDrawView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清理过程
}


// CDrawView 诊断

#ifdef _DEBUG
void CDrawView::AssertValid() const
{
	CScrollView::AssertValid();
}

void CDrawView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

CDrawDoc* CDrawView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDrawDoc)));
	return (CDrawDoc*)m_pDocument;
}
#endif //_DEBUG


// CDrawView 消息处理程序

void CDrawView::OnDrawTools(UINT nID)
{
	m_index = nID;
}

void CDrawView::OnUpdateDrawTools(CCmdUI* pCmdUI)
{
	pCmdUI->SetCheck(m_index == pCmdUI->m_nID);
}

void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
	SLayer* pLayer = nullptr;
	switch (m_index) {
	case ID_DRAW_LINE:
		pLayer = new CLine;
		break;
	case ID_DRAW_RECT:
		pLayer = new CRectO;
		break;
	case ID_DRAW_PENCIL:
		pLayer = new CPenCil;
		break;
	case ID_DRAW_DRAG:// 拖拽
		break;
	case ID_DRAW_ELLIPSE:
		pLayer = new CEllipse;
		break;
	case ID_DRAW_RRECT:
		pLayer = new CRRect;
		break;
	}
	if (pLayer) {
		pLayer->m_clBrush = m_colorBox.GetBlushColor();
		pLayer->m_clPen = m_colorBox.GetPenColor();
		pLayer->OnLButtonDown(nFlags, point);
		m_ls.Add(pLayer);
	}
	CScrollView::OnLButtonDown(nFlags, point);
}


void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
	SLayer::m_last = {MAXWORD, MAXWORD};// 上次点恢复未绘制状态
	int nCount = m_ls.GetCount();
	if (nCount < 1) {
		return;
	}
	m_ls[nCount - 1]->OnLButtonUp(nFlags, point);
	Invalidate(FALSE);

	CScrollView::OnLButtonUp(nFlags, point);
}


void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
	int nCount = m_ls.GetCount();
	if (nCount < 1) {
		return;
	}
	if (SLayer::ST_DRAW == m_ls[nCount - 1]->m_stat) {
		CClientDC dc(this);
		if (m_index == ID_DRAW_LINE) {
			dc.SetROP2(R2_NOT);// 反色线
		}
		m_ls[nCount - 1]->OnMouseMove(nFlags, point, &dc);
		if (m_index != ID_DRAW_LINE) {
			Invalidate(FALSE);// 反色线不用刷新
		}
	}

	CScrollView::OnMouseMove(nFlags, point);
}

// Invalidate(TRUE) 先触发WM_ERASEBKGND背景消息OnEraseBkgnd回调；再触发WM_PAINT消息OnPaint回调
// 设计的目的是背景覆盖前景，方便刷新
BOOL CDrawView::OnEraseBkgnd(CDC* pDC)
{
	// return CScrollView::OnEraseBkgnd(pDC);
	return TRUE;
}


void CDrawView::OnSize(UINT nType, int cx, int cy)
{
	CScrollView::OnSize(nType, cx, cy);

	// 缩放后要重建
	m_dc.DeleteDC();
	m_dc.Create(cx, cy);
}


BOOL CDrawView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
	auto nCount = m_ls.GetCount();
	if (m_index == ID_DRAW_DRAG)
	{
		CPoint point;
		GetCursorPos(&point);
		ScreenToClient(&point);
		if (CheckLayer(point))
		{
			SetCursor(theApp.m_hDrag);
			return TRUE;
		}
	}
	else
	{
		SetCursor(theApp.m_hDraw);
		return TRUE;
	}

	return CScrollView::OnSetCursor(pWnd, nHitTest, message);
}
